/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package technotheist.imgcog.base;

/**
 * This project is the intellectual property and only to be used under license
 * guidelines. Please see the containing license.txt file for license
 * information and availability of use. The author takes no responsibility for
 * any damage or non-functionality caused by use of this software.
 *
 * For use of any content with a different license, please contact the author.
 *
 * @author Mitchel Strachan <technotheist@gmail.com>
 */
public final class Dimension {

    boolean isLessThan(Dimension other) {
        for(int i = 0; i < type.dimCnt; i++) {
            if(this.dim[i] >= other.dim[i]) {
                return false;
            }
        }
        return true;
    }
    
    static enum Type {
        Dim1D(1), Dim2D(2), Dim3D(3)
        
        ;
        public final int dimCnt;
        Type(int dimCnt) {
            this.dimCnt = dimCnt;
        }
        
        static Type getType(int dCnt) {
            if(dCnt > 0 && dCnt < 4) {
                return values()[dCnt-1];
            }
            return null;
        }
    }

    public final Type type;
    public final int cellCount;
    protected final int[] dim;

    public Dimension(int... dims) {
        this.type = Type.getType(dims.length);
        this.dim = dims;
        this.cellCount = product(dims);
    }

    public int len(int n) {
        return this.dim[n];
    }

    public static int product(int[] n) {
        return product(n, 0, n.length);
    }

    public static int product(int[] n, int fi, int len) {
        try {
            int sum = 1;
            for (int i = fi; i < fi + len; i++) {
                sum *= n[i];
            }
            return sum;
        } catch (ArrayIndexOutOfBoundsException e) {
            System.err.println("Exception : incorrect product limits ; " + e.toString());
            return -1;
        }
        
    }
    
    public boolean equals(Dimension other) {
        if(other.cellCount == this.cellCount && other.type == this.type) {
            for(int i = 0; i < type.dimCnt; i++) {
                if(other.dim[i] != this.dim[i]) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    public boolean greaterThanEqual(Dimension other) {
        if(other.type == this.type) {
            for(int i = 0; i < type.dimCnt; i++) {
                if(other.dim[i] > this.dim[i]) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    
    public boolean greaterThanEqual(Dimension adda, Dimension addb) {
        if(adda.type == this.type && addb.type == this.type) {
            for(int i = 0; i < type.dimCnt; i++) {
                if(adda.dim[i] + addb.dim[i] > this.dim[i]) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    
    public static class MismatchedDimensionsException extends Exception {
        
        public MismatchedDimensionsException() {
            super("Mismatched Dimension Error: Arguaments have diffent number of dimensions");
        }
    }
    
}
